﻿using Mbl.ParameterizedTest.FluentCollectionBuilding.Expectors.GeneralExpectations;
using Mbl.ParameterizedTest.FluentCollectionBuilding.Expectors.ObjectExpectations;

namespace Mbl.ParameterizedTest.FluentCollectionBuilding.Expectors
{
    public abstract class Expector<TIn1, TOut, TCollector>
        where TCollector : ITestCollector<TIn1, TOut>
    {
        private readonly TCollector _testRowCollector;
        private readonly TestCase<TIn1, TOut> _testCase;

        protected Expector(TCollector testRowCollector, TestCase<TIn1, TOut> testCase)
        {
            _testRowCollector = testRowCollector;
            _testCase = testCase;
        }

        protected Justifier<TIn1, TOut, TCollector> CreateJustifier(IExpectation<TOut> expectation)
        {
            _testCase.Expectation = expectation;
            return new Justifier<TIn1, TOut, TCollector>(_testRowCollector, _testCase);
        }        

		public Justifier<TIn1, TOut, TCollector> Expect(TOut expected)
        {
            return CreateJustifier(new EqualityExpectation<TOut>(expected));
        }

		public Justifier<TIn1, TOut, TCollector> ExpectNull()
        {
            return CreateJustifier(new NullExpectation<TOut>());
        }

		public Justifier<TIn1, TOut, TCollector> ExpectException<TException>()
			where TException : System.Exception
        {
            return CreateJustifier(new ExceptionExpectation<TOut, TException>());
        }
    }

    public abstract class Expector<TIn1, TIn2, TOut, TCollector>
        where TCollector : ITestCollector<TIn1, TIn2, TOut>
    {
        private readonly TCollector _testRowCollector;
        private readonly TestCase<TIn1, TIn2, TOut> _testCase;

        protected Expector(TCollector testRowCollector, TestCase<TIn1, TIn2, TOut> testCase)
        {
            _testRowCollector = testRowCollector;
            _testCase = testCase;
        }

        protected Justifier<TIn1, TIn2, TOut, TCollector> CreateJustifier(IExpectation<TOut> expectation)
        {
            _testCase.Expectation = expectation;
            return new Justifier<TIn1, TIn2, TOut, TCollector>(_testRowCollector, _testCase);
        }        

		public Justifier<TIn1, TIn2, TOut, TCollector> Expect(TOut expected)
        {
            return CreateJustifier(new EqualityExpectation<TOut>(expected));
        }

		public Justifier<TIn1, TIn2, TOut, TCollector> ExpectNull()
        {
            return CreateJustifier(new NullExpectation<TOut>());
        }

		public Justifier<TIn1, TIn2, TOut, TCollector> ExpectException<TException>()
			where TException : System.Exception
        {
            return CreateJustifier(new ExceptionExpectation<TOut, TException>());
        }
    }

    public abstract class Expector<TIn1, TIn2, TIn3, TOut, TCollector>
        where TCollector : ITestCollector<TIn1, TIn2, TIn3, TOut>
    {
        private readonly TCollector _testRowCollector;
        private readonly TestCase<TIn1, TIn2, TIn3, TOut> _testCase;

        protected Expector(TCollector testRowCollector, TestCase<TIn1, TIn2, TIn3, TOut> testCase)
        {
            _testRowCollector = testRowCollector;
            _testCase = testCase;
        }

        protected Justifier<TIn1, TIn2, TIn3, TOut, TCollector> CreateJustifier(IExpectation<TOut> expectation)
        {
            _testCase.Expectation = expectation;
            return new Justifier<TIn1, TIn2, TIn3, TOut, TCollector>(_testRowCollector, _testCase);
        }        

		public Justifier<TIn1, TIn2, TIn3, TOut, TCollector> Expect(TOut expected)
        {
            return CreateJustifier(new EqualityExpectation<TOut>(expected));
        }

		public Justifier<TIn1, TIn2, TIn3, TOut, TCollector> ExpectNull()
        {
            return CreateJustifier(new NullExpectation<TOut>());
        }

		public Justifier<TIn1, TIn2, TIn3, TOut, TCollector> ExpectException<TException>()
			where TException : System.Exception
        {
            return CreateJustifier(new ExceptionExpectation<TOut, TException>());
        }
    }

    public abstract class Expector<TIn1, TIn2, TIn3, TIn4, TOut, TCollector>
        where TCollector : ITestCollector<TIn1, TIn2, TIn3, TIn4, TOut>
    {
        private readonly TCollector _testRowCollector;
        private readonly TestCase<TIn1, TIn2, TIn3, TIn4, TOut> _testCase;

        protected Expector(TCollector testRowCollector, TestCase<TIn1, TIn2, TIn3, TIn4, TOut> testCase)
        {
            _testRowCollector = testRowCollector;
            _testCase = testCase;
        }

        protected Justifier<TIn1, TIn2, TIn3, TIn4, TOut, TCollector> CreateJustifier(IExpectation<TOut> expectation)
        {
            _testCase.Expectation = expectation;
            return new Justifier<TIn1, TIn2, TIn3, TIn4, TOut, TCollector>(_testRowCollector, _testCase);
        }        

		public Justifier<TIn1, TIn2, TIn3, TIn4, TOut, TCollector> Expect(TOut expected)
        {
            return CreateJustifier(new EqualityExpectation<TOut>(expected));
        }

		public Justifier<TIn1, TIn2, TIn3, TIn4, TOut, TCollector> ExpectNull()
        {
            return CreateJustifier(new NullExpectation<TOut>());
        }

		public Justifier<TIn1, TIn2, TIn3, TIn4, TOut, TCollector> ExpectException<TException>()
			where TException : System.Exception
        {
            return CreateJustifier(new ExceptionExpectation<TOut, TException>());
        }
    }

    public abstract class Expector<TIn1, TIn2, TIn3, TIn4, TIn5, TOut, TCollector>
        where TCollector : ITestCollector<TIn1, TIn2, TIn3, TIn4, TIn5, TOut>
    {
        private readonly TCollector _testRowCollector;
        private readonly TestCase<TIn1, TIn2, TIn3, TIn4, TIn5, TOut> _testCase;

        protected Expector(TCollector testRowCollector, TestCase<TIn1, TIn2, TIn3, TIn4, TIn5, TOut> testCase)
        {
            _testRowCollector = testRowCollector;
            _testCase = testCase;
        }

        protected Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TOut, TCollector> CreateJustifier(IExpectation<TOut> expectation)
        {
            _testCase.Expectation = expectation;
            return new Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TOut, TCollector>(_testRowCollector, _testCase);
        }        

		public Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TOut, TCollector> Expect(TOut expected)
        {
            return CreateJustifier(new EqualityExpectation<TOut>(expected));
        }

		public Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TOut, TCollector> ExpectNull()
        {
            return CreateJustifier(new NullExpectation<TOut>());
        }

		public Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TOut, TCollector> ExpectException<TException>()
			where TException : System.Exception
        {
            return CreateJustifier(new ExceptionExpectation<TOut, TException>());
        }
    }

    public abstract class Expector<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut, TCollector>
        where TCollector : ITestCollector<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut>
    {
        private readonly TCollector _testRowCollector;
        private readonly TestCase<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut> _testCase;

        protected Expector(TCollector testRowCollector, TestCase<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut> testCase)
        {
            _testRowCollector = testRowCollector;
            _testCase = testCase;
        }

        protected Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut, TCollector> CreateJustifier(IExpectation<TOut> expectation)
        {
            _testCase.Expectation = expectation;
            return new Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut, TCollector>(_testRowCollector, _testCase);
        }        

		public Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut, TCollector> Expect(TOut expected)
        {
            return CreateJustifier(new EqualityExpectation<TOut>(expected));
        }

		public Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut, TCollector> ExpectNull()
        {
            return CreateJustifier(new NullExpectation<TOut>());
        }

		public Justifier<TIn1, TIn2, TIn3, TIn4, TIn5, TIn6, TOut, TCollector> ExpectException<TException>()
			where TException : System.Exception
        {
            return CreateJustifier(new ExceptionExpectation<TOut, TException>());
        }
    }

}